home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * Here's a similar snippet for Solaris
- * using the procfs interface...
- *
- * Daniel Brown, dbrown@ccdc.cam.ac.uk
- *
- */
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/param.h>
- #include <sys/syscall.h>
- #include <sys/uio.h>
-
- #include <fcntl.h>
- #include <procfs.h>
- #include <stdio.h>
- #include <unistd.h>
-
- /* Faking of the time() system call via procfs.
- *
- * Daniel Brown, dbrown@ccdc.cam.ac.uk
- *
- * Compiled and tested under Solaris 2.6/sparc and 2.6/x86
- */
-
- int
- read_status(pid_t pid, pstatus_t *status)
- {
- char buf[MAXPATHLEN];
- int fd;
-
- sprintf(buf, "/proc/%d/status", (int) pid);
-
- if ((fd = open(buf, O_RDONLY)) == -1)
- {
- perror("read_status(open)");
- return 1;
- }
-
- if (read(fd, (void *) status, sizeof(pstatus_t)) != sizeof(pstatus_t))
- {
- perror("read_status(read)");
- return 1;
- }
- close(fd);
-
- return 0;
- }
-
- int
- write_ctl(pid_t pid, long syscall, void *arg, size_t arglen)
- {
- int fd;
- char buf[MAXPATHLEN];
- struct iovec vec[2];
-
- sprintf(buf, "/proc/%d/ctl", (int) pid);
-
- if ((fd = open(buf, O_WRONLY)) == -1)
- {
- perror("write_ctl(open)");
- return 1;
- }
-
- vec[0].iov_base = (void *) &syscall;
- vec[0].iov_len = sizeof(long);
-
- if (arg != NULL)
- {
- vec[1].iov_base = arg;
- vec[1].iov_len = arglen;
-
- if (writev(fd, vec, 2) != (vec[0].iov_len + vec[1].iov_len))
- {
- perror("write_ctl(write2)");
- close(fd);
- return 1;
- }
- }
- else
- {
- if (writev(fd, vec, 1) != vec[0].iov_len)
- {
- perror("write_ctl(write1)");
- return 1;
- }
- }
-
- close(fd);
-
- return 0;
- }
-
- int
- main(int argc, char **argv)
- {
- pid_t pid, ppid;
- pstatus_t pstatus;
- sysset_t sysset;
- long val;
-
- setvbuf(stdout, (char *) NULL, _IONBF, (size_t) 0);
-
- ppid = getpid();
-
- if (read_status(ppid, &pstatus))
- exit(1);
-
- printf("Parent PID is %d\n", (int) ppid);
-
- printf("Setting PCSEXIT for time() : stop on exit from time().\n");
-
- premptyset(&sysset);
- praddset(&sysset, SYS_time);
-
- if (write_ctl(ppid, PCSEXIT, (void *) &sysset, sizeof(sysset_t)))
- exit(1);
-
- printf("Setting PR_FORK, so that the child inherits these traps.\n");
-
- val = PR_FORK;
-
- if (write_ctl(ppid, PCSET, (void *) &val, sizeof(long)))
- exit(1);
-
- printf("Finally, setting PCSENTRY for exit() "
- ": stop on entry to exit().\n");
-
- premptyset(&sysset);
- praddset(&sysset, SYS_exit);
-
- if (write_ctl(ppid, PCSENTRY, (void *) &sysset, sizeof(sysset_t)))
- exit(1);
-
- if ((pid = fork()) < 0)
- {
- perror("fork");
- exit(1);
- }
- else if (pid > 0)
- { /* Parent */
-
- printf("Clearing exit() trap for the parent...\n");
-
- premptyset(&sysset);
- if (write_ctl(ppid, PCSENTRY, (void *) &sysset,
- sizeof(sysset_t)))
- exit(1); /* Good luck! */
-
- if (read_status(pid, &pstatus))
- exit(1);
-
- printf("Child PID is %d and %s have a trap set on time().\n",
- (int) pstatus.pr_pid,
- (prismember(&pstatus.pr_sysexit,
- SYS_time)) ? "does" : "doesn't");
-
- while (1)
- {
-
- printf("Waiting for child to call time() or exit().\n");
-
- if (write_ctl(pid, PCWSTOP, (void *) 0, 0))
- exit(1);
-
- printf("Write PCWSTOP returned. Reading status.\n");
-
- if (read_status(pid, &pstatus))
- exit(1);
-
- if (pstatus.pr_lwp.pr_syscall == SYS_exit)
- {
- printf("Child has called exit(). Bye!\n");
- exit(0);
- }
- else if (pstatus.pr_lwp.pr_syscall != SYS_time)
- {
- printf("We've caught syscall %d! Eeeek!\n",
- (int) pstatus.pr_lwp.pr_syscall);
- exit(1);
- }
-
- printf("Child has called time().\n");
-
- printf("LWP register R_R0 is %d.\n",
- (int) pstatus.pr_lwp.pr_reg[R_R0]);
-
- printf("Setting LWP register R_R0 to 123.\n");
-
- pstatus.pr_lwp.pr_reg[R_R0] = 123;
- if (write_ctl(pid, PCSREG, (void *) &pstatus.pr_lwp.pr_reg,
- sizeof(prgregset_t)))
- exit(1);
-
- printf("Restarting the child.\n");
-
- val = 0L;
-
- if (write_ctl(pid, PCRUN, (void *) &val, sizeof(long)))
- exit(1);
-
- printf("Restarted.\n");
-
- } /* while (1) */
-
- /* NOT REACHED */
- }
-
- /* Child */
-
- sleep(5);
-
- execl("/usr/bin/date", "/usr/bin/date", (char *) NULL);
-
- perror("execl failed");
-
- return 99;
- }
- /* www.hack.co.za [2000]*/